package com.excel.service.excel.v1;




import com.corpgovernment.job.dao.entity.db.JobDo;
import com.corpgovernment.job.service.JobService;
import com.corpgovernment.organization.Bo.SyncEmployeeInfoBo;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.entity.SyncEmployeeCallBackRequestEntity;
import com.corpgovernment.organization.entity.db.MbImportExcelRecord;
import com.corpgovernment.organization.entity.db.MbOrgInfo;
import com.corpgovernment.organization.entity.db.MbPostInfo;
import com.corpgovernment.organization.entity.db.MbUserOrgRelation;
import com.corpgovernment.organization.enumm.ServiceErrorEnum;
import com.corpgovernment.organization.mapper.MbUserOrgRelationMapper;
import com.corpgovernment.organization.service.IOrganizationInfoService;
import com.corpgovernment.organization.service.IPostService;
import com.corpgovernment.permission.entity.db.MbRole;
import com.corpgovernment.permission.service.RoleService;
import com.ctrip.corp.obt.generic.core.context.RequestContext;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.EncryptUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.excel.model.ExcelImportConfig;
import com.excel.service.excel.*;
import com.excel.util.ExcelImportUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;

import static com.corpgovernment.permission.config.PermissionFilter.DATA_PERMISSION_ORG_ID_LIST;

/**
 * 员工
 *
 * @author hc
 */
@Service
@Slf4j
public class EmployUpProcessorV1<T> extends EmployAddProcessorV1<T> implements ExcelImportProcessor<SyncEmployeeCallBackRequestEntity.FailInfo,SyncEmployeeInfoBo, MbImportExcelRecord, T> {

    @Autowired
    private IOrganizationInfoService organizationInfoService;
    @Autowired
    private IPostService postService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private JobService jobService;
    @Autowired
    private ExcelImportUtil excelImportUtil;
    @Autowired
    private MbUserOrgRelationMapper userOrgRelationMapper;

    private static final String ENCRYPT_KEY = "1234567890123456";



    @Override
    public BizImportPreInsertResult<SyncEmployeeCallBackRequestEntity.FailInfo, SyncEmployeeInfoBo, T> checkDbDataWithPreInsert(List<SyncEmployeeInfoBo> list) {


        BizImportPreInsertResultImpl<SyncEmployeeCallBackRequestEntity.FailInfo, SyncEmployeeInfoBo, T> result = new BizImportPreInsertResultImpl();

        List<SyncEmployeeCallBackRequestEntity.FailInfo> errorList = new ArrayList<>();
        List<SyncEmployeeInfoBo> dataList = new ArrayList<>();

        List<String> uids = list.stream().filter(f-> StringUtils.isNotBlank(f.getUid())).map(SyncEmployeeInfoBo::getUid).collect(Collectors.toList());
        List<String> businessCodes = list.stream().filter(f-> StringUtils.isNotBlank(f.getBusinessCode())).map(SyncEmployeeInfoBo::getBusinessCode).collect(Collectors.toList());
        List<String> phoneSm4Encrypts = list.stream().filter(f-> StringUtils.isNotBlank(f.getMobilePhone())).map(s -> EncryptUtils.sm4Encrypt(s.getMobilePhone(), ENCRYPT_KEY)).collect(Collectors.toList());

        Map<String, Boolean> uidMap = excelImportUtil.isExistByFieldInDb("mb_org_employee_info","uid",uids,true);

        Map<String, Boolean> businessCodeMap = excelImportUtil.isExistByFieldInDb("mb_org_info","business_code",businessCodes,true);

        Map<String, Boolean> phoneMap = excelImportUtil.isExistByFieldInDb("mb_org_employee_info","mobile_phone",phoneSm4Encrypts,true);

        Map<String, List<SyncEmployeeInfoBo>> uidEmpInfoMap = list.stream().collect(Collectors.groupingBy(SyncEmployeeInfoBo::getUid));

        // 需要新增的信息 岗位 + 职级
        List<T> needInsertList = new ArrayList<>();


        // 新增 校验db是否存在的uid phone 和 上级组织编码
        for (SyncEmployeeInfoBo item : list) {

            if(uidMap.containsKey(item.getUid()) && !uidMap.get(item.getUid())){
                SyncEmployeeCallBackRequestEntity.FailInfo errorLog = new SyncEmployeeCallBackRequestEntity.FailInfo();
                errorLog.setMainLineNo(item.getLineNo());
                errorLog.setLineNo(item.getLineNo());
                errorLog.setSheetName(SyncEmployeeInfoBo.SheetEnum.EMP.getName());
                errorLog.setSheetIndex(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex());
                errorLog.setFailReason(OrganizationResponseCodeEnum.UID_DONT_EXISTS.message());
                errorList.add(errorLog);
            }

            if(businessCodeMap.containsKey(item.getBusinessCode()) && !businessCodeMap.get(item.getBusinessCode())){
                SyncEmployeeCallBackRequestEntity.FailInfo errorLog = new SyncEmployeeCallBackRequestEntity.FailInfo();
                errorLog.setMainLineNo(item.getLineNo());
                errorLog.setLineNo(item.getLineNo());
                errorLog.setSheetName(SyncEmployeeInfoBo.SheetEnum.EMP.getName());
                errorLog.setSheetIndex(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex());
                errorLog.setFailReason(ServiceErrorEnum.SyncHumanResources_SyncEmployeeInfo_company_Null_Failure.getErrorMessage());
                errorList.add(errorLog);
            }else {
                MbOrgInfo thisItem = organizationInfoService.findByBusinessCode(item.getBusinessCode());
                item.setOrgId(thisItem.getOrgId());
                item.setMbPostList(new ArrayList<>());
                item.setJobDoList(new ArrayList<>());
                // 获取当前excel填写的组织编码 的最近一级的公司信息 -匹配职级
                MbOrgInfo mbOrgInfo = organizationInfoService.findFirstCompany(thisItem.getOrgId());
                if(mbOrgInfo!= null){
                    item.setFirstCorgId(mbOrgInfo.getOrgId());
                    List<MbRole> mbRoles = roleService.listCorpRoles(mbOrgInfo.getOrgId());
                    item.setMbRoleList(mbRoles);
                    List<MbPostInfo> postInfos = postService.listByOrgIds(Collections.singletonList(mbOrgInfo.getOrgId()));
                    item.setMbPostList(postInfos);
                }
                List<JobDo> jobDoList = jobService.listJobBoByOrgId(item.getOrgId());
                item.setJobDoList(jobDoList);
            }

            String phoneSm4Encrypt = EncryptUtils.sm4Encrypt(item.getMobilePhone(), ENCRYPT_KEY);
            if(phoneMap.containsKey(phoneSm4Encrypt) && !phoneMap.get(phoneSm4Encrypt)){
                SyncEmployeeCallBackRequestEntity.FailInfo errorLog = new SyncEmployeeCallBackRequestEntity.FailInfo();
                errorLog.setMainLineNo(item.getLineNo());
                errorLog.setLineNo(item.getLineNo());
                errorLog.setSheetName(SyncEmployeeInfoBo.SheetEnum.EMP.getName());
                errorLog.setSheetIndex(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex());
                errorLog.setFailReason(OrganizationResponseCodeEnum.EMPLOYEE_PHONE_NO_EXIST.message());
                errorList.add(errorLog);
            }
            // 职级校验
            checkPostFromDb(errorList, needInsertList, item);


            ServiceErrorEnum superiorErrorEnum = this.checkSuperiorInfo(item.getManageUid(),uidEmpInfoMap);
            if (!ServiceErrorEnum.Success.getErrorCode().equals(superiorErrorEnum.getErrorCode())) {
                SyncEmployeeCallBackRequestEntity.FailInfo errorLog = new SyncEmployeeCallBackRequestEntity.FailInfo();
                errorLog.setMainLineNo(item.getLineNo());
                errorLog.setLineNo(item.getLineNo());
                errorLog.setSheetName(SyncEmployeeInfoBo.SheetEnum.EMP.getName());
                errorLog.setSheetIndex(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex());
                errorLog.setFailReason(superiorErrorEnum.getErrorMessage());
                errorList.add(errorLog);
            }

            ServiceErrorEnum employeeRoleNameErrorEnum = this.checkEmployeeRoleName(item);
            if (!ServiceErrorEnum.Success.getErrorCode().equals(employeeRoleNameErrorEnum.getErrorCode())) {
                SyncEmployeeCallBackRequestEntity.FailInfo errorLog = new SyncEmployeeCallBackRequestEntity.FailInfo();
                errorLog.setMainLineNo(item.getLineNo());
                errorLog.setLineNo(item.getLineNo());
                errorLog.setSheetName(SyncEmployeeInfoBo.SheetEnum.EMP.getName());
                errorLog.setSheetIndex(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex());
                errorLog.setFailReason(employeeRoleNameErrorEnum.getErrorMessage());
                errorList.add(errorLog);
            }

            // 岗位校验
            checkJobFromDb(errorList, needInsertList, item);

            // 证件校验
            checkCardListFromDb(errorList, item);

            dataList.add(item);
        }

        result.setErrorList(errorList);
        result.setDataList(dataList);
        result.setPreInsertList(needInsertList);
        return result;
    }

    @Override
    public BizImportResult<SyncEmployeeCallBackRequestEntity.FailInfo, SyncEmployeeInfoBo> checkDataPermission(List<SyncEmployeeInfoBo> list) {
        BizImportResultImpl<SyncEmployeeCallBackRequestEntity.FailInfo,SyncEmployeeInfoBo> result = new BizImportResultImpl<>();
        List<SyncEmployeeCallBackRequestEntity.FailInfo> errorList = new ArrayList<>();
        List<SyncEmployeeInfoBo> dataList = new ArrayList<>();
        for (SyncEmployeeInfoBo item : list) {

            checkPermissionByOrgId(errorList, item);

            dataList.add(item);
        }

        result.setErrorList(errorList);
        result.setDataList(dataList);
        return result;
    }

    private void checkPermissionByOrgId(List<SyncEmployeeCallBackRequestEntity.FailInfo> errorList, SyncEmployeeInfoBo item) {
        List<MbUserOrgRelation> mbUserOrgRelations = userOrgRelationMapper.listByUids(Collections.singletonList(item.getUid()));
        // excel uid映射的orgId
        List<String> uidOrgIds = mbUserOrgRelations.stream()
                .map(MbUserOrgRelation::getOrgId)
                .filter(id -> StringUtils.isNotBlank(id))
                .distinct()
                .collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(uidOrgIds)){
            List<String> orgIds = (List<String>) RequestContext.getCurrentContext().getContextParams(DATA_PERMISSION_ORG_ID_LIST);
            log.info("登录用户拥有的部门权限为{},上传excel员工编号所属的部门为{}", JsonUtils.toJsonString(orgIds),uidOrgIds.get(0));
            if(CollectionUtils.isNotEmpty(orgIds) && !orgIds.contains(uidOrgIds.get(0))){
                SyncEmployeeCallBackRequestEntity.FailInfo errorLog = new SyncEmployeeCallBackRequestEntity.FailInfo();
                errorLog.setMainLineNo(item.getLineNo());
                errorLog.setLineNo(item.getLineNo());
                errorLog.setSheetName(SyncEmployeeInfoBo.SheetEnum.EMP.getName());
                errorLog.setSheetIndex(SyncEmployeeInfoBo.SheetEnum.EMP.getIndex());
                errorLog.setFailReason(OrganizationResponseCodeEnum.UID_DONT_PERMISSION.message());
                errorList.add(errorLog);
            }
        }
    }


    @Override
    public String getTag() {
        return "employ_update_v1";
    }

    @Override
    public ExcelImportConfig getConfig() {
        ExcelImportConfig config = new ExcelImportConfig();
        config.setIsSharding(true);
        config.setIgnoreHeader(true);
        config.setRollBackType(1);
        return config;
    }


}
